﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace TestListGenerator.Common
{
    /// <summary>
    /// Used to dump common types
    /// </summary>
    public class Dumper
    {
        /// <summary>
        /// Dumps an exception with some details about it
        /// </summary>
        /// <param name="ex">The exception to dump</param>
        /// <returns>A string representing the exception</returns>
        public static string Dump(Exception ex)
        {
            if (ex == null)
            {
                return "Exception was null";
            }
            return "Exception Type: " + ex.GetType().FullName + "\n" +
                "Message: " + ex.Message + "\n" +
                "Stack Trace: " + ex.StackTrace;
        }

        /// <summary>
        /// Dumps out a whole object - useful for debugging
        /// </summary>
        /// <param name="obj">The object to dump</param>
        /// <returns>A string representing the objects name and current values</returns>
        public static string Dump(object obj)
        {
            StringBuilder result = new StringBuilder();

            // These are the standard binding flags that we are going to use
            BindingFlags flags = 
                  BindingFlags.Public | 
                  BindingFlags.NonPublic | 
                  BindingFlags.Instance;

            Type myType = obj.GetType();
            result.AppendLine(string.Format("Type: {0}", myType));

            // Write out the fields
            result.AppendLine("\tType Fields: ");
            foreach (MemberInfo member in myType.GetFields(flags)) 
            {
                FieldInfo fi = member as FieldInfo;
                var myValue = fi.GetValue(obj);
                result.AppendLine(string.Format("\t\t{0}: {1}", 
                    member.Name, 
                    myValue));
            }

            // Write out the properties
            result.AppendLine("\tType Properties: ");
            foreach (MemberInfo member in myType.GetProperties(flags))
            {
                PropertyInfo pi = member as PropertyInfo;
                var myValue = pi.GetValue(obj, null);

                result.AppendLine(string.Format("\t\t{0}: {1}",
                    member.Name,
                    myValue));
            }

            return result.ToString();
        }
    }
}
